package com.songlanyun.common.wxUtils;

import com.songlanyun.common.utils.DateUtil;
import com.songlanyun.common.utils.R;
import com.songlanyun.common.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付返回的通用字符串
 **/
@Component
@Slf4j
public class PayCommon {


    /**
     * 微信支付
     **/
//    public R wxPay(WxPayTools payInfo) {
//        // 生成微信「统一下单」请求数据
//        Map<String, String> dataMap = new HashMap<>(16);
//        dataMap.put("appid", wxPay.getAppId());
//        dataMap.put("mch_id", wxPay.getMchID());
//        dataMap.put("nonce_str", UUIDUtil.getUUID());
//        dataMap.put("sign_type", payInfo.getSignType());
//        dataMap.put("body", wxPay.getBody());
//        dataMap.put("out_trade_no", payInfo.getOrderNo());
//        dataMap.put("total_fee", payInfo.getMoney());
//        dataMap.put("spbill_create_ip", HttpClientUtil.localIp());
//        dataMap.put("notify_url", payInfo.getNotifyUrl());
//        dataMap.put("trade_type", wxPay.getTradeTypeJsApi());
//        dataMap.put("attach", payInfo.getNotifyUrl());
//        dataMap.put("openid", payInfo.getOpenId());
//
//        try {
//            // 签名,请求「统一下单」接口，并解析返回结果
//            Map<String, String> responseMap = signAndGetResponse(dataMap, wxPay.getPayKey(),
//                    wxPay.getFieldSign(), wxPay.getUnifiedOrderUrl());
//            log.info("微信支付结果返回：" + responseMap);
//            if (responseMap == null || responseMap.isEmpty()) {
//                return null;
//            }
//            // 生成客户端「调起支付接口」的请求参数
////            Map<String, String> resultMap = getJsApiPayOrder(responseMap,wxPayConfig.getKey(),
//////                    wxPayConfig.getFieldSign(),"prepay_id=" + responseMap.get("prepay_id"),
//////                    wxPayConfig.getSignType());
//            Map<String, String> resultMap = getJsApiPayOrder(responseMap, wxPay.getPayKey(),
//                    wxPay.getFieldSign(), "prepay_id=" + responseMap.get("prepay_id"), wxPay.getSignType());
//            // 添加预支付订单创建成功标识
//            resultMap.put("pre_pay_order_status", wxPay.getResponseSuccess());
//            return R.ok().put("payInfo", resultMap);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return R.error("支付异常！");
//        }
//    }


    /**
     * 生成签名,调用微信「统一下单」接口，并解析接口返回结果
     *
     * @param dataMap   请求参数
     * @param key       app Key
     * @param signField 签名字段
     * @param apiUrl    微信接口地址
     * @return
     */
    private static Map<String, String> signAndGetResponse(Map<String, String> dataMap, String key,
                                                          String signField, String apiUrl) throws Exception {
        // 生成签名 MD5 编码

        String md5Sign = WxPaySignatureUtils.signature(dataMap, key);


        dataMap.put("sign", md5Sign);
        // 发送请求数据
        String respXml = HttpClientUtil.requestWithoutCert(apiUrl, dataMap,
                5000, 10000);
        // 解析请求数据
        dataMap.clear();
        dataMap = processResponseXml(respXml, key, signField);
        log.info("微信返回结果：" + dataMap);
        // 没有生成预支付订单,返回空
        if (org.apache.commons.lang.StringUtils.isEmpty(dataMap.get("prepay_id"))) {
            return null;
        }
        return dataMap;
    }

    private static Map<String, String> processResponseXml(String xmlStr, String key, String signField)
            throws Exception {
        String returnCodeField = "return_code";
        String resultFail = "FAIL";
        String resultSuccess = "SUCCESS";
        String returnCode;
        Map<String, String> respData = MapUtil.xml2Map(xmlStr);
        if (respData.containsKey(returnCodeField)) {
            returnCode = respData.get(returnCodeField);
        } else {
            throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));
        }
        if (returnCode.equalsIgnoreCase(resultFail)) {
            return respData;
        } else if (returnCode.equalsIgnoreCase(resultSuccess)) {
            /**
             * 签名校验
             */
            if (SignUtil.signValidate(respData, key, signField)) {
                return respData;
            } else {
                throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));
            }
        } else {
            throw new Exception(String.format("return_code value %s is invalid in XML: %s", returnCode, xmlStr));
        }
    }

    /**
     * 生成微信 JSAPI/小程序 支付「调起支付接口」请求参数
     *
     * @param data       接口参数
     * @param key        商户号支付秘钥 key
     * @param fieldSign  签名字段
     * @param packageStr 微信支付扩展字段(prepay_id=wx111....)
     * @param signType   签名类型
     * @return
     */
    private static Map<String, String> getJsApiPayOrder(Map<String, String> data, String key, String fieldSign,
                                                        String packageStr, String signType) throws Exception {
        Map<String, String> resultMap = new HashMap<>(16);
        resultMap.put("appId", data.get("appid"));
        resultMap.put("timeStamp", DateUtil.getTimeStampSecond());
        resultMap.put("nonceStr", UUIDUtil.getUUID());
        resultMap.put("package", packageStr);
        resultMap.put("signType", signType);
        // 生成签名
        String sign = SignUtil.getMD5Sign(resultMap, key, fieldSign);
        resultMap.put("paySign", sign);

        return resultMap;
    }

    public String wxReturnStr() {
        Map<String, String> resultMap = new HashMap<>(16);
        resultMap.put("return_code", "SUCCESS");
        resultMap.put("return_msg", "OK");
        String resultV = MapUtil.map2Xml(resultMap);
        return resultV;
    }

    public String wxFallReturnStr() {
        Map<String, String> resultMap = new HashMap<>(16);
        resultMap.put("return_code", "FAIL");
        resultMap.put("return_msg", "OK");
        String resultV = MapUtil.map2Xml(resultMap);
        return resultV;
    }
}
